<template>
    <div class="right-board">
        <el-tabs v-model="currentTab" class="center-tabs">
            <el-tab-pane label="组件属性" name="field"/>
            <el-tab-pane label="表单属性" name="form"/>
        </el-tabs>
        <div class="field-box">
            <el-scrollbar class="right-scrollbar">
                <!-- 组件属性 -->
                <el-form v-show="currentTab==='field' && showField" size="small" label-width="90px">
                    <el-form-item v-if="hasData && activeData.__config__.changeTag" label="组件类型">
                        <el-select
                            v-model="activeData.__config__.tagIcon"
                            placeholder="请选择组件类型"
                            :style="{width: '100%'}"
                            @change="tagChange"
                        >
                            <el-option-group v-for="group in tagList" :key="group.label" :label="group.label">
                                <el-option
                                    v-for="item in group.options"
                                    :key="item.__config__.label"
                                    :label="translate(item.__config__.label)"
                                    :value="item.__config__.tagIcon"
                                >
                                    <i :class="item.__config__.tagIcon" style="font-size: 16px"
                                       v-if="isElementIcon(item.__config__.tagIcon)"/>
                                    <vab-icon v-else
                                              :icon="item.__config__.tagIcon"/>
                                    <span> {{ translate(item.__config__.label) }}</span>
                                </el-option>
                            </el-option-group>
                        </el-select>
                    </el-form-item>
                    <el-form-item v-if="hasData && activeData.__vModel__!==undefined" label="字段名">
                        <el-input v-model="activeData.__vModel__" placeholder="请输入字段名（v-model）"/>
                    </el-form-item>
                    <el-form-item v-if=" hasData && activeData.__config__.componentName!==undefined"
                                  label="组件名">
                        {{ activeData.__config__.componentName }}
                    </el-form-item>
                    <el-form-item v-if="hasData && activeData.__config__.label!==undefined" label="标题">
                        <el-input v-model="activeData.__config__.label" placeholder="请输入标题" @input="changeRenderKey"/>
                    </el-form-item>
                    <el-form-item v-if="hasData && activeData.placeholder!==undefined" label="占位提示">
                        <el-input v-model="activeData.placeholder" placeholder="请输入占位提示" @input="changeRenderKey"/>
                    </el-form-item>
                    <el-form-item v-if="hasData && activeData.__config__.span!==undefined" label="表单栅格">
                        <el-slider v-model="activeData.__config__.span" :max="24" :min="1" :marks="{12:''}"
                                   @change="spanChange"/>
                    </el-form-item>
                    <el-form-item
                        v-if="hasData && activeData.__config__.layout==='rowFormItem'&&activeData.gutter!==undefined"
                        label="栅格间隔">
                        <el-input-number v-model="activeData.gutter" :min="0" placeholder="栅格间隔"/>
                    </el-form-item>
                    <el-form-item
                        v-if="hasData && activeData.__config__.layout==='rowFormItem'&&activeData.type!==undefined"
                        label="布局模式">
                        <el-radio-group v-model="activeData.type">
                            <el-radio-button label="default"/>
                            <el-radio-button label="flex"/>
                        </el-radio-group>
                    </el-form-item>
                    <el-form-item
                        v-if="hasData && activeData.justify!==undefined&&activeData.type==='flex'"
                        label="水平排列">
                        <el-select v-model="activeData.justify" placeholder="请选择水平排列" :style="{width: '100%'}">
                            <el-option
                                v-for="(item, index) in justifyOptions"
                                :key="index"
                                :label="item.label"
                                :value="item.value"
                            />
                        </el-select>
                    </el-form-item>
                    <el-form-item
                        v-if="hasData && activeData.align!==undefined&&activeData.type==='flex'"
                        label="垂直排列">
                        <el-radio-group v-model="activeData.align">
                            <el-radio-button label="top"/>
                            <el-radio-button label="middle"/>
                            <el-radio-button label="bottom"/>
                        </el-radio-group>
                    </el-form-item>
                    <el-form-item v-if="hasData && activeData.__config__.labelWidth!==undefined"
                                  label="标签宽度">
                        <el-input v-model.number="activeData.__config__.labelWidth" type="number"
                                  placeholder="请输入标签宽度"/>
                    </el-form-item>
                    <el-form-item v-if="hasData && activeData.style&&activeData.style.width!==undefined"
                                  label="组件宽度">
                        <el-input v-model="activeData.style.width" placeholder="请输入组件宽度" clearable/>
                    </el-form-item>
                    <el-form-item v-if="hasData && activeData.__vModel__!==undefined" label="默认值">
                        <el-input
                            :value="setDefaultValue(activeData.__config__.defaultValue)"
                            placeholder="请输入默认值"
                            @input="onDefaultValueInput"
                        />
                    </el-form-item>
                    <el-form-item v-if="hasData && activeData.autosize !== undefined" label="最小行数">
                        <el-input-number v-model="activeData.autosize.minRows" :min="1" placeholder="最小行数"/>
                    </el-form-item>
                    <el-form-item v-if="hasData && activeData.autosize !== undefined" label="最大行数">
                        <el-input-number v-model="activeData.autosize.maxRows" :min="1" placeholder="最大行数"/>
                    </el-form-item>
                    <el-form-item v-if="isShowMin" label="最小值">
                        <el-input-number v-model="activeData.min" placeholder="最小值"/>
                    </el-form-item>
                    <el-form-item v-if="isShowMax" label="最大值">
                        <el-input-number v-model="activeData.max" placeholder="最大值"/>
                    </el-form-item>
                    <el-form-item v-if="hasData && activeData.height!==undefined" label="组件高度">
                        <el-input-number v-model="activeData.height" placeholder="高度" @input="changeRenderKey"/>
                    </el-form-item>
                    <el-form-item v-if="isShowStep" label="步长">
                        <el-input-number v-model="activeData.step" placeholder="步数"/>
                    </el-form-item>
                    <el-form-item v-if="hasData && activeData.__config__.tag === 'el-input-number'"
                                  label="精度">
                        <el-input-number v-model="activeData.precision" :min="0" placeholder="精度"/>
                    </el-form-item>
                    <el-form-item v-if="hasData && activeData.__config__.tag === 'el-input-number'"
                                  label="按钮位置">
                        <el-radio-group v-model="activeData['controls-position']">
                            <el-radio-button label="">
                                默认
                            </el-radio-button>
                            <el-radio-button label="right">
                                右侧
                            </el-radio-button>
                        </el-radio-group>
                    </el-form-item>
                    <el-form-item v-if="hasData && activeData.maxlength !== undefined" label="最多输入">
                        <el-input v-model="activeData.maxlength" placeholder="请输入字符长度">
                            <template slot="append">
                                个字符
                            </template>
                        </el-input>
                    </el-form-item>
                    <template
                        v-if="hasData && ['el-checkbox-group', 'el-radio-group', 'el-select'].indexOf(activeData.__config__.tag) > -1">
                        <el-divider>选项</el-divider>
                        <draggable
                            :list="activeData.__slot__.options"
                            :animation="340"
                            group="selectItem"
                            handle=".option-drag"
                        >
                            <div v-for="(item, index) in activeData.__slot__.options" :key="index" class="select-item">
                                <div class="select-line-icon option-drag">
                                    <i class="el-icon-s-operation"/>
                                </div>
                                <el-input v-model="item.label" placeholder="选项名" size="small"/>
                                <el-input
                                    placeholder="选项值"
                                    size="small"
                                    :value="item.value"
                                    @input="setOptionValue(item, $event)"
                                />
                                <div class="close-btn select-line-icon"
                                     @click="activeData.__slot__.options.splice(index, 1)">
                                    <i class="el-icon-remove-outline"/>
                                </div>
                            </div>
                        </draggable>
                        <div style="margin-left: 20px;">
                            <el-button
                                style="padding-bottom: 0"
                                icon="el-icon-circle-plus-outline"
                                type="text"
                                @click="addSelectItem"
                            >
                                添加选项
                            </el-button>
                        </div>
                        <el-divider/>
                    </template>

                    <el-form-item v-if="hasData && activeData.__config__.showLabel !== undefined
            && activeData.__config__.labelWidth !== undefined" label="显示标签"
                    >
                        <el-switch v-model="activeData.__config__.showLabel"/>
                    </el-form-item>
                    <el-form-item
                        v-if="hasData && activeData.size !== undefined &&
              (activeData.__config__.optionType === 'button' ||
                activeData.__config__.border ||
                activeData.__config__.tag === 'el-color-picker' ||
                activeData.__config__.tag === 'el-button')"
                        label="组件尺寸"
                    >
                        <el-radio-group v-model="activeData.size">
                            <el-radio-button label="medium">
                                中等
                            </el-radio-button>
                            <el-radio-button label="small">
                                较小
                            </el-radio-button>
                            <el-radio-button label="mini">
                                迷你
                            </el-radio-button>
                        </el-radio-group>
                    </el-form-item>
                    <el-form-item v-if="hasData && activeData['show-word-limit'] !== undefined"
                                  label="输入统计">
                        <el-switch v-model="activeData['show-word-limit']"/>
                    </el-form-item>
                    <el-form-item v-if="hasData && activeData.__config__.tag === 'el-input-number'"
                                  label="严格步数">
                        <el-switch v-model="activeData['step-strictly']"/>
                    </el-form-item>
                    <el-form-item v-if="hasData && activeData.clearable !== undefined" label="能否清空">
                        <el-switch v-model="activeData.clearable"/>
                    </el-form-item>
                    <el-form-item v-if="hasData && activeData.__config__.showTip !== undefined"
                                  label="显示提示">
                        <el-switch v-model="activeData.__config__.showTip"/>
                    </el-form-item>
                    <el-form-item v-if="hasData && activeData.__config__.tag === 'el-upload'"
                                  label="多选文件">
                        <el-switch v-model="activeData.multiple"/>
                    </el-form-item>
                    <el-form-item v-if="hasData && activeData['auto-upload'] !== undefined" label="自动上传">
                        <el-switch v-model="activeData['auto-upload']"/>
                    </el-form-item>
                    <el-form-item v-if="hasData && activeData.readonly !== undefined" label="是否只读">
                        <el-switch v-model="activeData.readonly"/>
                    </el-form-item>
                    <el-form-item v-if="hasData && activeData.disabled !== undefined" label="是否禁用">
                        <el-switch v-model="activeData.disabled"/>
                    </el-form-item>
                    <el-form-item v-if="hasData && activeData.__config__.tag === 'el-select'"
                                  label="能否搜索">
                        <el-switch v-model="activeData.filterable"/>
                    </el-form-item>
                    <el-form-item v-if="hasData && activeData.__config__.tag === 'el-select'"
                                  label="是否多选">
                        <el-switch v-model="activeData.multiple" @change="multipleChange"/>
                    </el-form-item>
                    <el-form-item v-if="hasData && activeData.__config__.required !== undefined"
                                  label="是否必填">
                        <el-switch v-model="activeData.__config__.required"/>
                    </el-form-item>
                    <template v-if="hasData && isArray(activeData.__config__.regList)">
                        <el-divider>正则校验</el-divider>
                        <div
                            v-for="(item, index) in activeData.__config__.regList"
                            :key="index"
                            class="reg-item"
                        >
              <span class="close-btn" @click="activeData.__config__.regList.splice(index, 1)">
                <i class="el-icon-close"/>
              </span>
                            <el-form-item label="表达式">
                                <el-input v-model="item.pattern" placeholder="请输入正则"/>
                            </el-form-item>
                            <el-form-item label="错误提示" style="margin-bottom:0">
                                <el-input v-model="item.message" placeholder="请输入错误提示"/>
                            </el-form-item>
                        </div>
                        <div style="margin-left: 20px">
                            <el-button icon="el-icon-circle-plus-outline" type="text" @click="addReg">
                                添加规则
                            </el-button>
                        </div>
                    </template>
                </el-form>
                <!-- 表单属性 -->
                <el-form v-show="currentTab === 'form'" size="small" label-width="90px">
                    <el-form-item label="表单名">
                        <el-input v-model="formConf.formRef" placeholder="请输入表单名（ref）"/>
                    </el-form-item>
                    <el-form-item label="表单模型">
                        <el-input v-model="formConf.formModel" placeholder="请输入数据模型"/>
                    </el-form-item>
                    <el-form-item label="校验模型">
                        <el-input v-model="formConf.formRules" placeholder="请输入校验模型"/>
                    </el-form-item>
                    <el-form-item label="表单尺寸">
                        <el-radio-group v-model="formConf.size">
                            <el-radio-button label="medium">
                                中等
                            </el-radio-button>
                            <el-radio-button label="small">
                                较小
                            </el-radio-button>
                            <el-radio-button label="mini">
                                迷你
                            </el-radio-button>
                        </el-radio-group>
                    </el-form-item>
                    <el-form-item label="标签对齐">
                        <el-radio-group v-model="formConf.labelPosition">
                            <el-radio-button label="left">
                                左对齐
                            </el-radio-button>
                            <el-radio-button label="right">
                                右对齐
                            </el-radio-button>
                            <el-radio-button label="top">
                                顶部对齐
                            </el-radio-button>
                        </el-radio-group>
                    </el-form-item>
                    <el-form-item label="标签宽度">
                        <el-input v-model.number="formConf.labelWidth" type="number" placeholder="请输入标签宽度"/>
                    </el-form-item>
                    <el-form-item label="栅格间隔">
                        <el-input-number v-model="formConf.gutter" :min="0" placeholder="栅格间隔"/>
                    </el-form-item>
                    <el-form-item label="禁用表单">
                        <el-switch v-model="formConf.disabled"/>
                    </el-form-item>
                    <el-form-item label="表单按钮">
                        <el-switch v-model="formConf.formBtns"/>
                    </el-form-item>
                    <el-form-item label="显示未选中组件边框">
                        <el-switch v-model="formConf.unFocusedComponentBorder"/>
                    </el-form-item>
                </el-form>
            </el-scrollbar>
        </div>
    </div>
</template>

<script lang="ts">
    import Vue from "vue";
    import _ from 'lodash';
    import Component from "vue-class-component";
    import {Prop, Watch} from "vue-property-decorator";
    import FormConfigModel from "../model/form-config.model";
    import {
        InputComponents
    } from '../consts/const.js';
    import OptionModel from "../../../common/model/option.model";
    import draggable from 'vuedraggable'

    @Component({components: {draggable}})
    export default class rightPanel extends Vue {
        // 是否展示
        @Prop({default: false})
        private showField: boolean;
        // 当前操作数据
        @Prop({default: {}})
        private activeData: any;
        // 表单配置
        @Prop()
        private formConf: FormConfigModel;
        // 当前显示tab
        public currentTab: 'from' | 'field' = 'field';

        private currentNode;

        private currentIconModel;
        private justifyOptions: OptionModel[] = [
            {
                label: 'start',
                value: 'start'
            },
            {
                label: 'end',
                value: 'end'
            },
            {
                label: 'center',
                value: 'center'
            },
            {
                label: 'space-around',
                value: 'space-around'
            },
            {
                label: 'space-between',
                value: 'space-between'
            }
        ];
        private dateTimeFormat = {
            date: 'yyyy-MM-dd',
            week: 'yyyy 第 WW 周',
            month: 'yyyy-MM',
            year: 'yyyy',
            datetime: 'yyyy-MM-dd HH:mm:ss',
            daterange: 'yyyy-MM-dd',
            monthrange: 'yyyy-MM',
            datetimerange: 'yyyy-MM-dd HH:mm:ss'
        }


        get documentLink() {
            if (!_.isEmpty(this.activeData)) {
                return this.activeData.__config__.document;
            }
        }


        get tagList() {
            return [
                {
                    label: '输入型组件',
                    options: InputComponents
                }
            ]
        }

        get activeTag() {
            return this.hasData ? this.activeData.__config__.tag : '';
        }

        get isShowMin() {
            return ['el-input-number', 'el-slider'].indexOf(this.activeTag) > -1
        }

        get isShowMax() {
            return ['el-input-number', 'el-slider', 'el-rate'].indexOf(this.activeTag) > -1
        }

        get isShowStep() {
            return ['el-input-number', 'el-slider'].indexOf(this.activeTag) > -1
        }

        get hasData() {
            return !_.isEmpty(this.activeData);
        }

        get isArray() {
            return (obj) => {
                return _.isArray(obj);
            }
        };

        /**
         * 图标是否采用el图标
         */
        get isElementIcon() {
            return (iconName: string): boolean => {
                return iconName.startsWith("el");
            }
        }

        @Watch("handler", {immediate: true, deep: true})
        public handler(val) {
            console.log("formCfg" + val);
        }

        /**
         * 增加正则
         */
        addReg() {
            this.activeData.__config__.regList.push({
                pattern: '',
                message: ''
            })
        }

        /**
         * 增加选项
         */
        addSelectItem() {
            this.activeData.__slot__.options.push(new OptionModel())
        }

        append(data) {
            if (!data.children) {
                this.$set(data, 'children', [])
            }
            this.currentNode = data.children
        }

        remove(node, data) {
            this.activeData.__config__.defaultValue = [] // 避免删除时报错
            const {parent} = node
            const children = parent.data.children || parent.data
            const index = children.findIndex(d => d.id === data.id)
            children.splice(index, 1)
        }

        setOptionValue(item, val) {
            item.value = _.isNumber(val) ? +val : val
        }

        setDefaultValue(val) {
            if (_.isArray(val)) {
                return val.join(',')
            }
            if (typeof val === 'boolean') {
                return `${val}`
            }
            return val
        }

        onDefaultValueInput(str) {
            if (_.isArray(this.activeData.__config__.defaultValue)) {
                // 数组
                this.$set(
                    this.activeData.__config__,
                    'defaultValue',
                    str.split(',').map(val => (_.isNumber(val) ? +val : val))
                )
            } else if (['true', 'false'].indexOf(str) > -1) {
                // 布尔
                this.$set(this.activeData.__config__, 'defaultValue', JSON.parse(str))
            } else {
                // 字符串和数字
                this.$set(
                    this.activeData.__config__,
                    'defaultValue',
                    _.isNumber(str) ? +str : str
                )
            }
        }


        spanChange(val) {
            this.formConf.span = val
        }

        multipleChange(val) {
            this.$set(this.activeData.__config__, 'defaultValue', val ? [] : '')
        }


        tagChange(tagIcon) {
            let target = InputComponents.find(item => item.__config__.tagIcon === tagIcon)
            this.$emit('tag-change', target)
        }

        changeRenderKey() {
            // if (needRerenderList.includes(this.activeData.__config__.tag)) {
            //     this.activeData.__config__.renderKey = +new Date()
            // }
        }
        /**
         * 国际化
         */
        get translate() {
            return (key: string, param?: {}): string => {
                return this.$i18n.te(key) ? this.$i18n.t(key, param) as string : key;
            }
        }
    }
</script>

<style lang="scss" scoped>
    .right-board {
        width: 350px;
        position: absolute;
        right: 0;
        top: 0;
        padding-top: 3px;

        .field-box {
            position: relative;
            height: calc(100vh - 42px);
            box-sizing: border-box;
            overflow: hidden;
        }

        .el-scrollbar {
            height: 100%;
        }
    }

    .select-item {
        display: flex;
        border: 1px dashed #fff;
        box-sizing: border-box;

        & .close-btn {
            cursor: pointer;
            color: #f56c6c;
        }

        & .el-input + .el-input {
            margin-left: 4px;
        }
    }

    .select-item + .select-item {
        margin-top: 4px;
    }

    .select-item.sortable-chosen {
        border: 1px dashed #409eff;
    }

    .select-line-icon {
        line-height: 32px;
        font-size: 22px;
        padding: 0 4px;
        color: #777;
    }

    .option-drag {
        cursor: move;
    }

    .time-range {
        .el-date-editor {
            width: 227px;
        }

        ::v-deep .el-icon-time {
            display: none;
        }
    }

    .node-label {
        font-size: 14px;
    }

    .node-icon {
        color: #bebfc3;
    }
</style>
